package com.code.refactoring.hystrix;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * description:
 * author: wangxi
 * date:  2022/5/8 8:54 下午
 **/
@RestController
@RequestMapping("/orders")
@Slf4j
public class OrderController {

    /**
     * 超时降级策略
     *
     * @return
     */
    @PostMapping("/create")
    @HystrixCommand(commandKey = "/orders/create",
            commandProperties = {
                    @HystrixProperty(name = "execution.timeout.enabled", value = "true"),
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
            },
            fallbackMethod = "createOrderFallbackMethodTimeout")
    public String createOrder() {

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "success";
    }

    /**
     * 超时降级策略 createOrder超时降级
     *
     * @return
     */
    public String createOrderFallbackMethodTimeout() {
        log.info("--------超时降级策略执行--------");
        return "Hystrix time out";
    }

    /**
     * 限流策略：信号量方式
     * @return
     */
    @PostMapping("/insert")
    @HystrixCommand(commandKey = "/orders/insert",
            commandProperties = {
                    @HystrixProperty(name="execution.isolation.strategy",value="SEMAPHORE"),
                    @HystrixProperty(name="execution.isolation.semaphore.maxConcurrentRequests",value="3"),
            },
            fallbackMethod = "insertOrderFallbackMethodSemaphore")
    public String insertOrder(){

        return "success";
    }

    /**
     * 限流策略：信号量方式 insertOrder限流降级
     * @return
     */
    public String insertOrderFallbackMethodSemaphore(){
        log.info("--------信号量限流降级策略执行--------");
        return "Hystrix semaphore";
    }

    /**
     * 限流策略：线程池方式
     * @return
     */
    @PostMapping("/add")
    @HystrixCommand(commandKey = "/orders/add",
            commandProperties = {
                    @HystrixProperty(name="execution.isolation.strategy",value="THREAD")
            },
            threadPoolKey = "addOrderThreadPool",
            threadPoolProperties = {
                    @HystrixProperty(name="coreSize",value="10"),
                    @HystrixProperty(name="maxQueueSize",value="2000"),
                    @HystrixProperty(name="queueSizeRejectionThreshold",value="30")
            },
            fallbackMethod = "addOrderFallbackMethodThread")
    public String addOrder(){

        return "success";
    }

    /**
     *  限流策略：线程池方式 addOrder限流降级
     * @return
     */
    public String addOrderFallbackMethodThread(){
        log.info("--------线程池限流降级策略执行--------");
        return "Hystrix threadPool";
    }
}
